#include "hardware.h"
Hardware* hardware_this;

void Hardware::event_ini()
{
	ev_green = xTimerCreate("rgb",
			250 / portTICK_PERIOD_MS,
			pdTRUE, (void *)0, color_callback);
	ev_red = xTimerCreate("rgb",
			250 / portTICK_PERIOD_MS,
			pdTRUE, (void *)0, color_callback);
	ev_fliker = xTimerCreate("rgb",
			250 / portTICK_PERIOD_MS,
			pdTRUE, (void *)0, rgb_fliker_callback);
	ev_change = xTimerCreate("rgb",
			50 / portTICK_PERIOD_MS,
			pdTRUE, (void *)0, rgb_gradual_change_callback);
	hardware_this = this;
}
void Hardware::auto_task()
{
	wifi_close_task = xTimerCreate("wifi_task",
			60000 / portTICK_PERIOD_MS,
			pdTRUE, (void *)0, Wifi_close_callback);
	

	wifi_auto_task = xTimerCreate("wifi_task",
			5000 / portTICK_PERIOD_MS,
			pdTRUE, (void *)0, Wifi_auto_callback);

	xTimerStart(wifi_close_task, 0);	
	if (save_cfg.getString("autoconnect", "false")=="true")
	{
		WiFi.setSleep(true);
		WiFi.mode(WIFI_STA);
		xTimerStart(wifi_auto_task, 0);
	}
}

void Hardware::event_run(Event event)
{
    switch (event)
	{
		case RGB_CHANGE:init_rgb_gradual_change(); break;
		case GREEN:init_green(); break;
		case RED:  init_red(); break;
		case RGB_FLIKER: init_rgb_fliker(); break;
		case RESET: reset(); break;
		default:break;
	}
}

void Hardware::init_rgb_gradual_change()
{
	timergbevent = millis();
	if (xTimer_rgb==NULL)
	{
		rgb->setRGB(0, 0, 255);
		rgb->setBrightness(0.4); 
		xTimer_rgb = ev_change;
		xTimerStart(xTimer_rgb, 0);	
	}
	else if (xTimer_rgb != ev_change)
	{
		xTimerStop(xTimer_rgb, 0);
		rgb->setRGB(0, 0, 255);
		rgb->setBrightness(0.4); 
		xTimer_rgb = ev_change;
		xTimerStart(xTimer_rgb, 0);	
	}			
}

void Hardware::init_red()
{
	timergbevent = millis();
	if (xTimer_rgb==NULL)
	{
		rgb->setRGB(255, 0, 0);
		rgb->setBrightness(0.4); 
		xTimer_rgb = ev_red;
		xTimerStart(xTimer_rgb, 0);	
	}
	else if (xTimer_rgb != ev_red)
	{
		xTimerStop(xTimer_rgb, 0);
		rgb->setRGB(255, 0, 0);
		rgb->setBrightness(0.4); 
		xTimer_rgb = ev_red;
		xTimerStart(xTimer_rgb, 0);	
	}			
}

void Hardware::init_green()
{
	timergbevent = millis();
	if (xTimer_rgb==NULL)
	{
		rgb->setRGB(0, 255, 0);
		rgb->setBrightness(0.4); 
		xTimer_rgb = ev_green;
		xTimerStart(xTimer_rgb, 0);	
	}
	else if (xTimer_rgb != ev_green)
	{
		xTimerStop(xTimer_rgb, 0);
		rgb->setRGB(0, 255, 0);
		rgb->setBrightness(0.4); 
		xTimer_rgb = ev_green;
		xTimerStart(xTimer_rgb, 0);	
	}	
		
}

void Hardware::init_rgb_fliker()
{
	timergbevent = millis();
	if (xTimer_rgb==NULL)
	{
		rgb->setRGB(0, 0, 255);
		rgb->setBrightness(0.4); 
		xTimer_rgb = ev_fliker;
		xTimerStart(xTimer_rgb, 0);	
	}
	else if (xTimer_rgb != ev_fliker)
	{
		xTimerStop(xTimer_rgb, 0);
		rgb->setRGB(0, 0, 255);
		rgb->setBrightness(0.4); 
		xTimer_rgb = ev_fliker;
		xTimerStart(xTimer_rgb, 0);	
	}
}

void Hardware::rgb_gradual_change()
{
	if (millis()-timergbevent<45000)
	{
		h = (h+1)%256;
		rgb->setHSV(h, 255, 255);
	}
	else
	{
		xTimerStop(xTimer_rgb, 0);
        xTimer_rgb = NULL;
		rgb->setBrightness(0); 
	}
}

void Hardware::color()
{
	if (millis()-timergbevent>1000)
	{
		xTimerStop(xTimer_rgb, 0);
        xTimer_rgb = NULL;
		rgb->setBrightness(0); 
	}
}

void Hardware::rgb_fliker()
{
	if (millis()-timergbevent<2000)
	{
		h = (h+1)%2;
        if (h%2==0)
            rgb->setBrightness(0.4);
        else
            rgb->setBrightness(0);
	}
	else
	{
		xTimerStop(xTimer_rgb, 0);
        xTimer_rgb = NULL;
		rgb->setBrightness(0); 
	}
}

void Wifi_close_callback(TimerHandle_t xTimer)
{
	if (WiFi.getMode()!=WIFI_OFF&&WiFi.getMode()!=WIFI_AP&&WiFi.status()!=WL_CONNECTED)
	{
		WiFi.mode(WIFI_OFF);
	}
}

void Wifi_auto_callback(TimerHandle_t xTimer)
{
	if (WiFi.getMode()==WIFI_STA&&WiFi.status()!=WL_CONNECTED)
	{
		String ssid = hardware_this->save_cfg.getString("ssid", "");
		String password = hardware_this->save_cfg.getString("password", "");
		WiFi.begin(ssid.c_str(), password.c_str());
	}
	else{
		xTimerStop(hardware_this->wifi_auto_task, 0);
	}
}

void rgb_gradual_change_callback(TimerHandle_t xTimer)
{
	hardware_this->rgb_gradual_change();
}

void color_callback(TimerHandle_t xTimer)
{
	hardware_this->color();
}

void rgb_fliker_callback(TimerHandle_t xTimer)
{
	hardware_this->rgb_fliker();
}
